package com.zenithmind.mall.service.impl;

import com.zenithmind.common.exception.BusinessException;
import com.zenithmind.mall.mapper.CouponMapper;
import com.zenithmind.mall.mapper.ProductMapper;
import com.zenithmind.mall.mapper.UserCouponMapper;
import com.zenithmind.mall.pojo.entity.Coupon;
import com.zenithmind.mall.pojo.entity.Product;
import com.zenithmind.mall.pojo.entity.UserCoupon;
import com.zenithmind.mall.service.CouponCalculationService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * 优惠券计算服务实现类 - 遵循单一职责原则，专门负责优惠券的计算逻辑
 * 
 * @author ZenithMind Team
 * @since 2025-07-03
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class CouponCalculationServiceImpl implements CouponCalculationService {

    private final CouponMapper couponMapper;
    private final UserCouponMapper userCouponMapper;
    private final ProductMapper productMapper;

    @Override
    public Boolean checkCouponAvailable(String userCouponId, BigDecimal orderAmount) {
        UserCoupon userCoupon = userCouponMapper.selectById(userCouponId);
        if (userCoupon == null || userCoupon.getStatus() != 0) {
            return false;
        }
        
        Coupon coupon = couponMapper.selectById(userCoupon.getCouponId());
        if (coupon == null) {
            return false;
        }
        
        return coupon.isAvailable() && coupon.canUseForAmount(orderAmount);
    }

    @Override
    public BigDecimal calculateDiscountAmount(String userCouponId, BigDecimal orderAmount) {
        if (!checkCouponAvailable(userCouponId, orderAmount)) {
            return BigDecimal.ZERO;
        }
        
        UserCoupon userCoupon = userCouponMapper.selectById(userCouponId);
        Coupon coupon = couponMapper.selectById(userCoupon.getCouponId());
        
        return coupon.calculateDiscountAmount(orderAmount);
    }

    @Override
    public BigDecimal calculateBestDiscount(List<String> userCouponIds, BigDecimal orderAmount) {
        BigDecimal maxDiscount = BigDecimal.ZERO;
        
        for (String userCouponId : userCouponIds) {
            BigDecimal discount = calculateDiscountAmount(userCouponId, orderAmount);
            if (discount.compareTo(maxDiscount) > 0) {
                maxDiscount = discount;
            }
        }
        
        return maxDiscount;
    }

    @Override
    public List<String> getBestCouponCombination(List<String> userCouponIds, BigDecimal orderAmount) {
        List<String> bestCombination = new ArrayList<>();
        BigDecimal maxDiscount = BigDecimal.ZERO;
        
        // 目前只支持单张优惠券，后续可以扩展为多张组合
        for (String userCouponId : userCouponIds) {
            BigDecimal discount = calculateDiscountAmount(userCouponId, orderAmount);
            if (discount.compareTo(maxDiscount) > 0) {
                maxDiscount = discount;
                bestCombination.clear();
                bestCombination.add(userCouponId);
            }
        }
        
        return bestCombination;
    }

    @Override
    public Boolean isCouponApplicable(String userCouponId, List<String> productIds, List<String> categoryIds) {
        UserCoupon userCoupon = userCouponMapper.selectById(userCouponId);
        if (userCoupon == null) {
            return false;
        }
        
        Coupon coupon = couponMapper.selectById(userCoupon.getCouponId());
        if (coupon == null || !coupon.isAvailable()) {
            return false;
        }
        
        // 检查商品适用性
        if (coupon.getApplicableProducts() != null && !coupon.getApplicableProducts().trim().isEmpty()) {
            // 解析适用商品列表（JSON格式）
            // 这里简化处理，实际应该解析JSON
            String applicableProducts = coupon.getApplicableProducts();
            for (String productId : productIds) {
                if (!applicableProducts.contains(productId)) {
                    return false;
                }
            }
        }
        
        // 检查分类适用性
        if (coupon.getApplicableCategories() != null && !coupon.getApplicableCategories().trim().isEmpty()) {
            // 解析适用分类列表（JSON格式）
            String applicableCategories = coupon.getApplicableCategories();
            
            // 获取商品的分类
            for (String productId : productIds) {
                Product product = productMapper.selectById(productId);
                if (product != null && product.getCategoryId() != null) {
                    if (!applicableCategories.contains(product.getCategoryId())) {
                        return false;
                    }
                }
            }
        }
        
        return true;
    }

    /**
     * 验证优惠券计算结果的合理性
     */
    private boolean validateDiscountAmount(BigDecimal discount, BigDecimal orderAmount, Coupon coupon) {
        // 折扣金额不能为负数
        if (discount.compareTo(BigDecimal.ZERO) < 0) {
            return false;
        }
        
        // 折扣金额不能超过订单金额
        if (discount.compareTo(orderAmount) > 0) {
            return false;
        }
        
        // 满减券的折扣金额不能超过设定的金额
        if (coupon.isFullReductionCoupon() && coupon.getAmount() != null) {
            if (discount.compareTo(coupon.getAmount()) > 0) {
                return false;
            }
        }
        
        // 折扣券的折扣金额不能超过最大优惠金额
        if (coupon.isDiscountCoupon() && coupon.getAmount() != null) {
            if (discount.compareTo(coupon.getAmount()) > 0) {
                return false;
            }
        }
        
        return true;
    }

    /**
     * 记录优惠券使用日志
     */
    private void logCouponUsage(String userCouponId, BigDecimal orderAmount, BigDecimal discountAmount) {
        log.info("优惠券使用记录: userCouponId={}, orderAmount={}, discountAmount={}", 
                userCouponId, orderAmount, discountAmount);
    }
}
